package com.jbm.jbmsupplier.util;

import com.google.protobuf.ByteString;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Iterator;
import java.util.List;

/**
 * Created by root on 16-5-6.
 */
public class TransClass
{
	protected static String CamelCase ( String name )
	{
		char nm[] = name.toCharArray();

		for ( int i = 0; i < nm.length; i ++ )
		{
			if ( nm[i] >= 'a' && nm[i] <= 'z' && ( i == 0 || nm[i-1] == '_') )
				nm[i] += ( 'A' - 'a' );
		}

		return String.valueOf(nm).replaceAll("_", "");
	}

	protected static boolean P2I ( Field field, Object pb, Object iface )
	{
		// 权限修饰符
		int mo = field.getModifiers();
		String priv = Modifier.toString(mo);
		// 属性类型
		Class<?> type = field.getType();

		String name = field.getName();

		int isclass = type.getName().indexOf("jbmsupplier");

		if ( type.isArray() && type.getComponentType() != byte.class )
		{
			String getlist = "get"+CamelCase(name)+"List";
			String getcount = "get"+CamelCase(name)+"Count";
			Object value = null;
			List<?> listpb = null;

			try
			{
				Method getlistm = pb.getClass().getMethod(getlist);
				Method getcountm = pb.getClass().getMethod(getcount);
				listpb = (List<?>)getlistm.invoke(pb);
				int count = Integer.parseInt(getcountm.invoke(pb).toString());

				value=Array.newInstance(type.getComponentType(), count);

				Iterator it = listpb.iterator();
				int i = 0;
				while ( it.hasNext())
				{
					Object li_value = it.next();
					if ( isclass != -1 )
						li_value = ProtocolBufferToI ( li_value );
					Array.set(value,i,li_value);
					i++;
				}
				field.setAccessible(true);
				field.set(iface, value);
			}catch ( Exception e)
			{
				e.printStackTrace();
			}
		}else
		{
			String get = "get"+CamelCase(name);
			String has = "has"+CamelCase(name);
			Object value = null;

			try
			{
				Method getm = pb.getClass().getMethod(get);
				Method hasm = pb.getClass().getMethod(has);
				if ( ( Boolean)hasm.invoke(pb) )
				{
					value = getm.invoke(pb);
					if (isclass != -1)
						value = ProtocolBufferToI(value);
					else if ( type.isArray() && type.getComponentType() == byte.class )
					{
						ByteString bs = (ByteString)value;
						value = bs.toByteArray();
					}
					field.setAccessible(true);
					field.set(iface, value);
				}
			}catch ( Exception e)
			{
				e.printStackTrace();
			}
		}

		return true;
	}

	protected static boolean I2P ( Field field, Object pb, Object iface )
	{
		// 权限修饰符
		int mo = field.getModifiers();
		String priv = Modifier.toString(mo);
		// 属性类型
		Class<?> type = field.getType();

		String name = field.getName();

		int isclass = type.getName().indexOf("jbmsupplier");

		if ( type.isArray() && type.getComponentType() != byte.class )
		{
			String add = "add" + CamelCase(name);
			Object value = null;

			try
			{
				field.setAccessible(true);
				value = field.get(iface);
				String svn = value.getClass().getComponentType().getSimpleName();
				Method addm = null;

				if ( isclass != -1 )
					addm = pb.getClass().getMethod(add,Class.forName("com.jbm.jbmsupplier.pb.PB"+svn+"$"+svn));
				else
					addm = pb.getClass().getMethod(add,type.getComponentType());

				int count = Array.getLength(value);

				for ( int i = 0; i < count; i ++ )
				{
					Object li_value = Array.get(value,i);

					if ( isclass != -1 )
						li_value = ItoProtocolBuffer(li_value);

					addm.invoke(pb,li_value);
				}
			}catch (Exception e)
			{
				e.printStackTrace();
			}
		}else
		{
			String set = "set" + CamelCase(name);
			Object value = null;

			try
			{
				field.setAccessible(true);
				value = field.get(iface);
				Method setm = null;
				String svn = value.getClass().getSimpleName();

				if ( isclass != -1 )
				{
					setm = pb.getClass().getMethod(set, Class.forName("com.jbm.jbmsupplier.pb.PB" + svn + "$" + svn));
					value = ItoProtocolBuffer(value);
				}else if ( type.isArray() && type.getComponentType() == byte.class )
				{
					setm = pb.getClass().getMethod(set,ByteString.class);
				}else
					setm = pb.getClass().getMethod(set,type);

				if ( type.isArray() && type.getComponentType() == byte.class )
					value = ByteString.copyFrom((byte[])value);

				setm.invoke(pb,value);
			}catch (Exception e)
			{
				System.out.println(e.getMessage());
			//	e.printStackTrace();
			}
		}
		return true;
	}

	public static Object ProtocolBufferToI (Object pb)
	{
		String iname = "com.jbm.jbmsupplier.util."+pb.getClass().getSimpleName();
		Class<?> demo = null;
		Object iface = null;

		try
		{
			demo = Class.forName(iname);
			iface = demo.newInstance();
		}catch (Exception e)
		{
			e.printStackTrace();
		}

		Field[] field = demo.getDeclaredFields();
/*		for (int i = 0; i < field.length; i++)
		{
			P2I( field[i], pb, iface);
		}*/
		// 取得实现的接口或者父类的属性
		Field[] field1 = demo.getFields();
		for (int j = 0; j < field1.length; j++)
		{
			P2I( field1[j], pb, iface);
		}

		return iface;
	}

	public static Object ItoProtocolBuffer ( Object iface )
	{
		String pbname = "com.jbm.jbmsupplier.pb.PB"+iface.getClass().getSimpleName()+"$"+iface.getClass().getSimpleName();
		Object pb = null;
		Object pbb = null;

		try
		{
			Method nb = Class.forName(pbname).getMethod("newBuilder");
			pbb = nb.invoke(null);
		}catch (Exception e)
		{
			System.out.println(e.getMessage());
		//	e.printStackTrace();
		}

		Class<?> demo = iface.getClass();

		Field[] field = demo.getDeclaredFields();
/*		for (int i = 0; i < field.length; i++)
		{
			I2P( field[i], pbb, iface);
		}*/
		// 取得实现的接口或者父类的属性
		Field[] field1 = demo.getFields();
		for (int j = 0; j < field1.length; j++)
		{
			I2P( field1[j], pbb, iface);
		}

		try
		{
			Method build = pbb.getClass().getMethod("build");
			pb = build.invoke(pbb);
		}catch (Exception e)
		{
			System.out.println(e.getMessage());
		//	e.printStackTrace();
		}

		return pb;
	}
}
